package lew.bing.novels;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

/**
 * Created by 刘国兵 on 2019/8/19.
 *
 * @author 刘国兵
 */
public abstract class JsoupNovelLoader extends AbstractNovelLoader {

    private int tryTimes;

    private String catalogueAddress;

    public JsoupNovelLoader(int tryTimes, String catalogueAddress) {
        this.tryTimes = tryTimes;
        this.catalogueAddress = catalogueAddress;
    }

    @Override
    protected Novel getFromAddress(String address) {
        Callable<Novel> callable = () -> {
            Connection connect = Jsoup.connect(address);
            Document document = connect.get();
            return contentAndTitle(document);
        };
        int tryTimes = this.tryTimes;
        while (tryTimes > 0) {
            try {
                return callable.call();
            } catch (Exception e) {
                tryTimes --;
            }
        }
        // 如果失败可以记录下来
        return null;
    }

    protected abstract Elements addressesHref(Document document);

    protected abstract Novel contentAndTitle(Document document);

    @Override
    public List<String> addresses() {

        Callable<List<String>> callable = () -> {
            Connection connect = Jsoup.connect(catalogueAddress);
            Document document = connect.get();
            String baseUri = document.baseUri();
            Elements elements = addressesHref(document);
            String httpMatch = "^http[s]?://*+$";
            return elements.stream()
                    .map(element -> {
                        String href = element.attr("href");
                        if (href == null) {
                            return href;
                        }
                        if (href.matches(httpMatch)) {
                            return href;
                        }
                        if (href.startsWith("/")) {
                            return baseUri + href;
                        }
                        return catalogueAddress + href;
                    }).collect(Collectors.toList());
        };
        int tryTimes = this.tryTimes;
        while (tryTimes > 0) {
            try {
                return callable.call();
            } catch (Exception e) {
                tryTimes --;
            }
        }
        // 如果失败可以记录下来
        return null;
    }



}
